#ifndef _DATE_H_
#define _DATE_H_

#include <sstream>
#include <iostream>
using namespace std;


/**
 * Implementation of the class Date.
 * Date holds information of the Year, Month and Day that are to be used.
 */
class Date
{

public:
	Date();
	Date(unsigned short day, unsigned short month, unsigned short year);
	Data(string day, string month, string year);
	Data(string d);
	virtual ~Date();

	// Year
        unsigned short getYear() const;
	void setYear(unsigned short year);

        // Month
	unsigned short getMonth() const;
	void setMonth(unsigned short month);

        // Day
	unsigned short getDay() const;
	void setDay(unsigned short day);

        // Date
        void setDate(unsigned short day, unsigned short month, unsigned short year);

        // Boolean operators
	bool operator==(const Date &date);
	bool operator<(const Date &date);

        // I/O operators
        string printDate(const Date & date);
		void newDate(Date &date);

        // Determines if the given year is a leap year
        bool leapYear(unsigned short year);

        // Exception handler classes
        class InvalidYear {
        private:
            unsigned short year;
        public:
            InvalidYear(unsigned short year) {this->year = year;}
            void printError(ostream & os) {
                os << "Year must be within " << minYear << " and " << maxYear <<
                        ". Given: " << year << endl;
            }
        };

        class InvalidMonth {
        private:
            unsigned short month;
        public:
            InvalidMonth(unsigned short month) {this->month = month;}
            void printError(ostream & os) {
                os << "Month must be within 1 and 12. Given: " << month << endl;
            }
        };

        class InvalidDay {
        private:
            unsigned short day;
        public:
            InvalidDay(unsigned short day) {this->day = day;}
            void printError(ostream & os) {
                os << "Month must be within 1 and 31 (April, June, September and November: 30. "
                        "February 29 ou 28). Given: " << day << endl;
            }
        };

private:
	unsigned short year;
	unsigned short month;
	unsigned short day;
        const static unsigned short minYear = 2000;
        const static unsigned short maxYear = 2200;

};
#endif // _DATE_H_
